package org.statewalker.fsm.providers.conf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.statewalker.fsm.providers.IFsmTransitions;
import org.statewalker.fsm.providers.IFsmTransitionsRegistry;

public class CompositeFsmTransitionsRegistry<SK, EK>
    implements
    IFsmTransitionsRegistry<SK, EK> {

    public static class CompositeFsmTransitions<SK, EK>
        implements
        IFsmTransitions<SK, EK> {

        private List<IFsmTransitions<SK, EK>> fList = new ArrayList<IFsmTransitions<SK, EK>>();

        /**
         * 
         */
        public CompositeFsmTransitions() {
        }

        public SK getDefaultTarget(EK event) {
            List<IFsmTransitions<SK, EK>> list = fList;
            SK result = null;
            for (IFsmTransitions<SK, EK> transitions : list) {
                result = transitions.getDefaultTarget(event);
            }
            return result;
        }

        public SK getTarget(SK from, EK event) {
            List<IFsmTransitions<SK, EK>> list = fList;
            SK result = null;
            for (IFsmTransitions<SK, EK> transitions : list) {
                result = transitions.getTarget(from, event);
            }
            return result;
        }

        public synchronized void registerTransitions(
            IFsmTransitions<SK, EK> transitions) {
            List<IFsmTransitions<SK, EK>> list = new ArrayList<IFsmTransitions<SK, EK>>(
                fList);
            list.add(transitions);
            fList = list;
        }

        public synchronized void unregisterTransitions(
            IFsmTransitions<SK, EK> transitions) {
            List<IFsmTransitions<SK, EK>> list = new ArrayList<IFsmTransitions<SK, EK>>(
                fList);
            fList.remove(transitions);
            fList = list;
        }

    }

    private Map<SK, CompositeFsmTransitions<SK, EK>> fTransitions = new HashMap<SK, CompositeFsmTransitions<SK, EK>>();

    /**
     * @see org.statewalker.fsm.providers.IFsmTransitionsRegistry#getTransitions(java.lang.Object)
     */
    public IFsmTransitions<SK, EK> getTransitions(SK stateKey) {
        return fTransitions.get(stateKey);
    }

    /**
     * @see org.statewalker.fsm.providers.IFsmTransitionsRegistry#registerTransitions(java.lang.Object,
     *      org.statewalker.fsm.providers.IFsmTransitions)
     */
    public synchronized void registerTransitions(
        SK stateKey,
        IFsmTransitions<SK, EK> transitions) {
        CompositeFsmTransitions<SK, EK> composite = fTransitions.get(stateKey);
        if (composite == null) {
            composite = new CompositeFsmTransitions<SK, EK>();
            fTransitions.put(stateKey, composite);
        }
        composite.registerTransitions(transitions);
    }

    /**
     * @see org.statewalker.fsm.providers.IFsmTransitionsRegistry#removeTransitions(java.lang.Object,
     *      org.statewalker.fsm.providers.IFsmTransitions)
     */
    public void removeTransitions(
        SK stateKey,
        IFsmTransitions<SK, EK> transitions) {
        CompositeFsmTransitions<SK, EK> composite = fTransitions.get(stateKey);
        if (composite != null) {
            composite.unregisterTransitions(transitions);
        }

    }

}
